using System.Xml.Serialization;

namespace NSecurity
{
    [XmlType(TypeName = "ace")]
    public class AccessControlEntry
    {
        public AccessControlEntry()
        {
        }

        public AccessControlEntry(string securable, string verb, string subject, AccessType accessType)
        {
            this.Securable = securable;
            this.Verb = verb;
            this.Subject = subject;
            this.AccessType = accessType;
        }

        public static AccessControlEntry Create<TSecurable, TVerb, TSubject>(TSecurable securable, TVerb verb, TSubject subject, AccessType accessType)
        {
            var result = new AccessControlEntry(AccessControlEntry.SecurableToString(securable)
                , AccessControlEntry.VerbToString(verb)
                , AccessControlEntry.SubjectToString(subject)
                , accessType);
            return result;
        }

        [XmlAttribute(AttributeName = "securable")]
        public string Securable { get; set; }

        [XmlAttribute(AttributeName = "verb")]
        public string Verb { get; set; }

        [XmlAttribute(AttributeName = "subject")]
        public string Subject { get; set; }

        [XmlAttribute(AttributeName = "access")]
        public AccessType AccessType { get; set; }

        public static string SubjectToString<TSubject>(TSubject subject)
        {
            if (subject is ISubject)
            {
                return (subject as ISubject).Name;
            }

            return subject.ToString();
        }

        public static string VerbToString<TVerb>(TVerb verb)
        {
            if (verb is IVerb)
            {
                return (verb as IVerb).Name;
            }

            return verb.ToString();
        }

        public static string SecurableToString<TSecurable>(TSecurable securable)
        {
            if (securable is ISecurable)
            {
                return (securable as ISecurable).Name;
            }

            return securable.ToString();
        }

    }
}